package model

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/BurntSushi/toml"
	"github.com/bndr/gojenkins"
	"github.com/cookieY/yee/logger"
)

type mysqlConfig struct {
	Host     string
	User     string
	Password string
	Db       string
	Port     string
	PrintSql bool
}

type general struct {
	SecretKey       string
	Host            string
	Hours           time.Duration
	GrpcAddr        string
	BasePath        string
	SqlFilePath     string
	RepoUrl         string
	RepoDir         string
	RepoUsername    string
	RepoPassword    string
	JenkinsUrl      string
	JenkinsUsername string
	JenkinsPassword string
	GitlabApiUrl    string
	GitlabToken     string
}

// AI配置结构
type aiConfig struct {
	ApiUrl              string  `toml:"ApiUrl"`
	ApiKey              string  `toml:"ApiKey"`
	Model               string  `toml:"Model"`
	MaxTokens           int     `toml:"MaxTokens"`
	Temperature         float64 `toml:"Temperature"`
	MaxTurns            int     `toml:"MaxTurns"`            // 最大对话轮数
	MaxHistoryMessages  int     `toml:"MaxHistoryMessages"`  // 最大历史消息数
	SessionTimeout      int     `toml:"SessionTimeout"`      // 会话超时时间（秒）
	EnableMultiTurn     bool    `toml:"EnableMultiTurn"`     // 启用多轮对话
	EnableToolChaining  bool    `toml:"EnableToolChaining"`  // 启用工具链式调用
	EnableContextMemory bool    `toml:"EnableContextMemory"` // 启用上下文记忆
}

// OIDC配置结构
type oidcConfig struct {
	// 基础配置
	Issuer  string `toml:"Issuer"`
	BaseUrl string `toml:"BaseUrl"`

	// 密钥配置
	SigningKey       string `toml:"SigningKey"`
	SigningAlgorithm string `toml:"SigningAlgorithm"`
	KeyId            string `toml:"KeyId"`

	// 令牌有效期配置(秒)
	AccessTokenTTL       int `toml:"AccessTokenTTL"`
	RefreshTokenTTL      int `toml:"RefreshTokenTTL"`
	AuthorizationCodeTTL int `toml:"AuthorizationCodeTTL"`
	IdTokenTTL           int `toml:"IdTokenTTL"`

	// 功能开关
	EnablePKCE                  bool `toml:"EnablePKCE"`
	EnableRefreshToken          bool `toml:"EnableRefreshToken"`
	EnableImplicitFlow          bool `toml:"EnableImplicitFlow"`
	EnableClientCredentialsFlow bool `toml:"EnableClientCredentialsFlow"`
	EnableDeviceFlow            bool `toml:"EnableDeviceFlow"`

	// 会话配置
	SessionTTL            int `toml:"SessionTTL"`
	RememberMeTTL         int `toml:"RememberMeTTL"`
	MaxConcurrentSessions int `toml:"MaxConcurrentSessions"`

	// 安全配置
	RequireHttps    bool   `toml:"RequireHttps"`
	SecureCookies   bool   `toml:"SecureCookies"`
	SameSiteCookies string `toml:"SameSiteCookies"`
	CSRFProtection  bool   `toml:"CSRFProtection"`

	// 缓存配置
	EnableCache bool   `toml:"EnableCache"`
	CacheTTL    int    `toml:"CacheTTL"`
	CachePrefix string `toml:"CachePrefix"`

	// 审计配置
	EnableAudit        bool   `toml:"EnableAudit"`
	AuditLevel         string `toml:"AuditLevel"`
	AuditRetentionDays int    `toml:"AuditRetentionDays"`

	// 登录页面配置
	LoginPageUrl   string `toml:"LoginPageUrl"`
	ConsentPageUrl string `toml:"ConsentPageUrl"`
	ErrorPageUrl   string `toml:"ErrorPageUrl"`
	LogoutPageUrl  string `toml:"LogoutPageUrl"`

	// 默认作用域
	DefaultScopes []string `toml:"DefaultScopes"`

	// 支持的响应类型
	SupportedResponseTypes []string `toml:"SupportedResponseTypes"`

	// 支持的授权类型
	SupportedGrantTypes []string `toml:"SupportedGrantTypes"`
}

type Config struct {
	General          general
	Mysql            mysqlConfig
	AI               aiConfig   // 添加AI配置
	OIDC             oidcConfig // 添加OIDC配置
	OIDCClientConfig oidcClientConfig
}
type Other struct {
	Limit            string   `json:"limit"`
	IDC              []string `json:"idc"`
	Multi            bool     `json:"multi"`
	Query            bool     `json:"query"`
	ExcludeDbList    []string `json:"exclude_db_list"`
	InsulateWordList []string `json:"insulate_word_list"`
	Register         bool     `json:"register"`
	Export           bool     `json:"export"`
	PerOrder         int      `json:"per_order"`
	ExQueryTime      int      `json:"ex_query_time"`
	QueryTimeout     int      `json:"query_timeout"`
}

type Message struct {
	WebHook  string `json:"web_hook"`
	Host     string `json:"host"`
	Port     int    `json:"port"`
	User     string `json:"user"`
	Password string `json:"password"`
	ToUser   string `json:"to_user"`
	Mail     bool   `json:"mail"`
	Ding     bool   `json:"ding"`
	Ssl      bool   `json:"ssl"`
	PushType bool   `json:"push_type"`
}

type Ldap struct {
	Url      string `json:"url"`
	User     string `json:"user"`
	Password string `json:"password"`
	Type     int    `json:"type"`
	Sc       string `json:"sc"`
	Ldaps    bool   `json:"ldaps"`
}

type PermissionList struct {
	DDLSource   []string `json:"ddl_source"`
	DMLSource   []string `json:"dml_source"`
	Auditor     []string `json:"auditor"`
	QuerySource []string `json:"query_source"`
}

type MargeList struct {
	DDL         int      `json:"ddl"`
	DDLSource   []string `json:"ddl_source"`
	DML         int      `json:"dml"`
	DMLSource   []string `json:"dml_source"`
	User        int      `json:"user"`
	Base        int      `json:"base"`
	Auditor     []string `json:"auditor"`
	Query       int      `json:"query"`
	QuerySource []string `json:"query_source"`
}

type Permission struct {
	Permissions PermissionList `json:"permissions"`
}

type Queryresults struct {
	Sql      string
	Basename string
	Source   string
}

type oidcClientConfig struct {
	Issuer       string `toml:"Issuer"`
	ClientID     string `toml:"ClientId"`
	ClientSecret string `toml:"ClientSecret"`
	RedirectURI  string `toml:"RedirectUri"`
	Scopes       string `toml:"Scopes"`
}

var C Config

var JenkinsConnection *gojenkins.Jenkins

var JWT_SECRET = ""
var JWT_EXPIRE = time.Hour * 24

var Host = ""

var GloLdap Ldap

var GloOther Other

var GloMessage Message

var BasePath = ""

var SqlFilePath = ""

var SystemFileSeparator = string(filepath.Separator)

var GloLogger logger.Logger

var GloOIDC oidcConfig // OIDC全局配置

func ConfigInit(c string) {
	GloLogger = logger.LogCreator(4)
	GloLogger.SetOut(os.Stdout)

	_, err := toml.DecodeFile(c, &C)
	if err != nil {
		GloLogger.Error(err.Error())
	}

	JWT_SECRET = C.General.SecretKey
	JWT_EXPIRE = C.General.Hours * time.Hour

	BasePath = C.General.BasePath
	SqlFilePath = C.General.SqlFilePath

	if !strings.HasSuffix(BasePath, "/") {
		BasePath = fmt.Sprintf("%s/", BasePath)
	}

	if !strings.HasSuffix(SqlFilePath, "/") {
		SqlFilePath = fmt.Sprintf("%s/", SqlFilePath)
	}

	// 初始化OIDC配置
	GloOIDC = C.OIDC

	JenkinsConnection, err = generalJenkinsConnection(context.Background())
	if err != nil {
		GloLogger.Error("jenkins连接失败!" + err.Error())
	}
}

// generalJenkinsConnection 建立jenkins连接
func generalJenkinsConnection(ctx context.Context) (*gojenkins.Jenkins, error) {
	jenkinsConn := gojenkins.CreateJenkins(nil, C.General.JenkinsUrl, C.General.JenkinsUsername, C.General.JenkinsPassword)
	// _, err := jenkinsConn.Init(ctx)
	// if err != nil {
	// 	GloLogger.Error(err.Error())
	// 	return nil, err
	// } else {
	// 	GloLogger.Info("jenkins连接成功!")
	// }
	return jenkinsConn, nil
}
